package org.visionlibrary.image.filters.bluring;

import java.awt.Point;

import org.visionlibrary.image.model.ConvolutionKernel;


public class MotionBlur {
	protected int size = 7;

	protected int direction = 3;

	protected Point origin = new Point(1, 1);

	public int getDirection() {
		return direction;
	}

	public Point getOrigin() {
		return origin;
	}

	public int getSize() {
		return size;
	}

	public void setOrigin(Point origin) {
		this.origin = origin;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public void setDirection(int direction) {
		this.direction = direction;
	}

	public ConvolutionKernel getFilterKernel() {
		float[] values = new float[size * size];

		if (direction == VERTICAL)
			return this.getVerticalKernel(values);
		else if (direction == HORIZONTAL)
			return this.getHorizontalKernel(values);
		else if (direction == ANGLE45)
			return this.getAngle45Kernel(values);
		else if (direction == ANGLE135)
			return this.getAngle135Kernel(values);
		else
			return this.getAllDirectionsKernel(values);
	}

	protected ConvolutionKernel getAllDirectionsKernel(float[] values) {
		if (values.length == 0)
			return null;

		ConvolutionKernel kernel = getVerticalKernel(values);
		float divisor = kernel.getDivisor();
		kernel = getHorizontalKernel(kernel.getKernelData());
		divisor += (kernel.getDivisor() - 1);
		kernel = getAngle135Kernel(kernel.getKernelData());
		divisor += (kernel.getDivisor() - 1);
		kernel = getAngle45Kernel(kernel.getKernelData());
		divisor += (kernel.getDivisor() - 1);

		kernel.setDivisor(divisor);

		return kernel;
	}

	protected ConvolutionKernel getAngle135Kernel(float[] values) {
		if (values.length == 0)
			return null;

		int start = size + 1;
		int i = 0;
		int index = 0;
		while (i < size) {
			values[index] = 1.0f;
			index += start;
			i++;
		}

		return new ConvolutionKernel(size, size, values, size, new Point(size / 2,
				size / 2));
	}

	protected ConvolutionKernel getAngle45Kernel(float[] values) {
		if (values.length == 0)
			return null;

		int start = size - 1;
		int i = 0;
		int index = start;
		while (i < size) {
			values[index] = 1.0f;
			index += start;
			i++;
		}

		return new ConvolutionKernel(size, size, values, size, new Point(size / 2,
				size / 2));
	}

	protected ConvolutionKernel getHorizontalKernel(float[] values) {
		if (values.length == 0)
			return null;

		int start = (size / 2) * size;
		int stop = start + size;

		java.util.Arrays.fill(values, start, stop, 1.0f);

		return new ConvolutionKernel(size, size, values, size, new Point(size / 2,
				size / 2));
	}

	protected ConvolutionKernel getVerticalKernel(float[] values) {
		if (values.length == 0)
			return null;

		int middle = size / 2;
		int i = 0;
		while (i < size * size) {
			values[i + middle] = 1.0f;
			i += size;
		}

		return new ConvolutionKernel(size, size, values, size, new Point(size / 2,
				size / 2));
	}

	public static final int VERTICAL = 1;

	public static final int HORIZONTAL = 2;

	public static final int ANGLE45 = 3;

	public static final int ANGLE135 = 4;

	public static final int ALLDIRECTIONS = 5;
}
